package com.woniu.shiro;


import com.woniu.domain.User;
import com.woniu.token.JWTUtil;
import com.woniu.token.MyJsonWebToken;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.omg.CORBA.DynAnyPackage.Invalid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;

import java.util.List;
import java.util.concurrent.TimeUnit;

@Component
public class MyRealm extends AuthorizingRealm {
//    @Autowired
//    private RbacManagerService rbacManagerService;
//    @Autowired
//    private RbacPermService rbacPermService;

    @Autowired(required = false)
    RedisTemplate redisTemplate;
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof MyJsonWebToken;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("MyRealm.doGetAuthorizationInfo, 授权方法进入!!!");
        String username = JWTUtil.getUserName(principalCollection.toString());
        //去数据库查出用户信息, 含角色(也可含权限, 看你实体怎么定义咯= =)
//        RbacManager rbacManager = rbacManagerService.managerGetByaccpunt(username);
        //从redis中通过token键值取出对应的对象
        User user =(User) redisTemplate.opsForValue().get(principalCollection.toString());
        //授权信息集合
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        //2.目前是单个角色则直接这样用吧.....
        simpleAuthorizationInfo.addRole(user.getRole().getRoleName());
        //3.通过角色, 去查询中间表 找到所有的权限  获取tyep字段,a接口权限link细节信息(同第1步)

        return simpleAuthorizationInfo;
    }

    /**
     * 身份认证方法
     * 需要在用户登录系统时触发
     * 该方法将是我们主要的方法, 流程是登录后, 携带token 与权限信息 发送到 vue中 存储浏览器
     * 在页面渲染时,直接传入菜单和 页面按钮显示权限
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String myJWT = (String)authenticationToken.getCredentials();
        String username = JWTUtil.getUserName(myJWT);
        if(username == null){
            throw new AuthenticationException("token无效");
        }
        Long expire = redisTemplate.getExpire(myJWT, TimeUnit.SECONDS);
        System.out.println("token还有"+expire+"过期");
        if(expire>0){
            //过期时间修改为30分钟
            redisTemplate.expire(myJWT,1800,TimeUnit.SECONDS);
        }
//        RbacManager rbacManager = rbacManagerService.managerGetByaccpunt(username);
        User user =(User) redisTemplate.opsForValue().get(myJWT);
        if(user == null){
            throw new AuthenticationException("账号不存在或信息已过期！");
        }
        if(JWTUtil.verify(myJWT,username,user.getPassword())){
            return new SimpleAuthenticationInfo(myJWT,myJWT,this.getName());
        }else{
            throw new  AuthenticationException("账号或密码错误！");
        }
    }
}
